package com.sdyeda.readiot;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.fazecast.jSerialComm.SerialPort;
import com.sdyeda.readiot.config.Setting;
import com.sdyeda.readiot.config.WriteLog;
import com.sdyeda.readiot.fx.MainWindowController;
import com.sdyeda.readiot.iotinfo.DtuInfo;
import com.sdyeda.readiot.iotinfo.IotInfo;
import com.sdyeda.readiot.iotinfo.JdbcIotInfo;
import com.sdyeda.readiot.iotinfo.ReadingInfo;


public class Read implements Runnable{
	
	private final Log log = LogFactory.getLog(this.getClass());
	
	
	private List<String> coms;
	private List<DtuInfo> dtus;
	
	private List<IotInfo> listIotinfo;
	

	public void ReadIots() {
		
		//设置正在读取标志 同时设置开始时间  
		((ReadingInfo)Setting.Get(Setting.READINGINFO)).setReading(true);

		listIotinfo = JdbcIotInfo.getall();
		if(null==listIotinfo) {
			log.error("获取传感器信息不成功，读取终止！");
			((ReadingInfo)Setting.Get(Setting.READINGINFO)).setReading(false);

			return;
		}
		//初始化
		((ReadingInfo)(Setting.Get(Setting.READINGINFO))).Init(listIotinfo);


		MainWindowController controller = (MainWindowController)(Setting.Get(Setting.MAINWINDOW_CONTROLLER));
		if(controller!=null) {
			controller.refushList();
		}

		//log.info(JSONObject.toJSONString(((ReadingInfo)(Setting.Get(Setting.READINGINFO)))));
		
		//统计串口 ip---
		coms = new ArrayList<String>();
		dtus = new ArrayList<>();

		listIotinfo.forEach(item->{
			if(item.isUsedtu()) {
				DtuInfo dtu = new DtuInfo(item.getIp(),item.getPort());
				if(!DtuInfo.find(dtu, dtus))
				dtus.add(dtu);
			}
			else {
				if (!coms.contains(item.getCom())) {
					coms.add(item.getCom());
				}
			}
		});
		
		
		
		//线程池
		List<Future<Integer>> futurelist = new ArrayList<Future<Integer>>();
		ExecutorService executorServer = Executors.newCachedThreadPool();

		coms.forEach(item->{
			//submit产生线程并执行
			Future<Integer> future = executorServer.submit(new ReadTask(item,getList(item)));
			futurelist.add(future);
		
			try {
				Thread.sleep(500);
			} 
			catch (InterruptedException e) {
			}
		});
		
		dtus.forEach(item ->{
			//此处不好理解，应解决
			Future<Integer> future = executorServer.submit(new ReadDtuTask(item,getList(item)));
			futurelist.add(future);
		
			try {
				Thread.sleep(500);
			} 
			catch (InterruptedException e) {
			}
			
		});
		
		//等待线程全部完成
		for (Future<Integer> future : futurelist) {
			try {
				future.get();
			} catch (Exception e) {
				e.printStackTrace();
			} 
		}
		
		coms.forEach(item -> {
			try {
				SerialPort port = SerialPort.getCommPort(item);
				if (port != null && port.isOpen()) {
					// System.out.println(port);
					port.closePort();
				}
			} catch (Exception e) {
			}
		});
		
		//设置正在读取标志 同时设置结束时间  
		((ReadingInfo)Setting.Get(Setting.READINGINFO)).setReading(false);
		if(controller!=null) {
			controller.refushList();
		}
				
		//// 写日志（读取情况统计）,每天一个文件，类似log/readinfo/2022-08-11.log ....
		try {
			WriteLog.WriteReaddingIofo();
		} catch (IOException e) {
		}

	}

	@Override
	public void run() {
		//System.out.println((Date)Setting.Get(Setting.VALID_TIME));
		if(new Date().before((Date)Setting.Get(Setting.VALID_TIME))) {
			ReadIots();
		}
		else {
			log.error("软件未注册或已经过期，请及时注册！");
		}
	}
	
	List<IotInfo> getList(String com){
		
		List<IotInfo> list = new ArrayList<>();
		listIotinfo.forEach(item->{
			if(item.getCom().equals(com) && !item.isUsedtu()) {
				list.add(item);
			}
		});
		return list;
	}

	List<IotInfo> getList(DtuInfo dtu){
		
		List<IotInfo> list = new ArrayList<>();
		listIotinfo.forEach(item->{
			if(item.getIp().equals(dtu.getIp()) && item.getPort()==dtu.getPort() && item.isUsedtu()) {
				list.add(item);
			}
		});
		return list;
	}

	
	public class ReadTask implements Callable<Integer> {

		private String com; 
		private List<IotInfo> listIotinfo;
		public ReadTask(String com,List<IotInfo> listIotinfo) {
			this.com =com;
			this.listIotinfo = listIotinfo;
		}
		
		@Override
		public Integer call() throws Exception {
			//log.info(com+"-------------------线程开始------------------");
			ReadTaskService task = new ReadTaskService();
			return task.ReadCom(com, listIotinfo);
		}
	}
	
	public class ReadDtuTask implements Callable<Integer> {

		private DtuInfo dtu; 
		private List<IotInfo> listIotinfo;
		public ReadDtuTask(DtuInfo dtu,List<IotInfo> listIotinfo) {
			this.dtu =dtu;
			this.listIotinfo = listIotinfo;
		}
		
		@Override
		public Integer call() throws Exception {
			//log.info(com+"-------------------线程开始------------------");
			ReadDtuTaskService task = new ReadDtuTaskService();
			return task.ReadCom(dtu, listIotinfo);
		}
	}

}
